Dealing with decimal places
Though we have placed dollar
signs in front of our totals, JavaScript is not aware that we are
dealing with monetary values. As far as the computer is concerned, these
are just numbers, and should be displayed as such. This means that if
the total ends in a zero after the decimal point, this will be chopped
off:
As we see here, the total that should read $1079.70 displays as $1079.7.
Even worse, the precision limitations of JavaScript can sometimes lead
to rounding errors. These can make the calculations appear completely
broken:
Fortunately, the fix for both problems is simple. JavaScript's Number class has several methods to deal with this sort of issue, and .toFixed()
fits the bill here. This method takes a number of decimal places as a
parameter, and returns a string representing the floating-point number
rounded to that many decimal places:
$('#cart tbody tr').each(function() {
var price = parseFloat($('td.price', this).text()
.replace(/^[^\d.]*/, ''));
price = isNaN(price) ? 0 : price;
var quantity = parseInt($('td.quantity input', this).val());
var cost = quantity * price;
$('td.cost', this).text('$' + cost.toFixed(2));
totalQuantity += quantity;
});
Now our totals all look like normal monetary values:
After a long series of
arithmetic operations, the rounding of floating-point numbers could
cause enough error to accumulate that even .toFixed()
cannot mask it. The safest way to handle manipulations of currency in
larger applications is to store and manipulate all values in cents, as
integers; decimal points can be added for display only.